from abc import ABC

from Alibb.handlers import BaseHandler
from tools.auth import authenticated_async
from apps.api.add_offer import AddOfferApi
from Alibb.form import InsertAttributeForm

from ujson import loads
from aiomysql import DictCursor


class PublishOfferHandler(BaseHandler, ABC):

    @staticmethod
    def join_param(sql_result):

        dict_ = {}

        if sql_result['LANGUAGE'].decode() != "CHINESE":
            raise Exception("非中文站商品")

        dict_['productType'] = sql_result['product_type']
        dict_['categoryID'] = sql_result['category_id']
        dict_['subject'] = sql_result['SUBJECT']
        dict_['language'] = sql_result['LANGUAGE'].decode()
        dict_['image'] = sql_result['image']
        dict_['webSite'] = sql_result['website']
        dict_['bizType'] = sql_result['biz_type']
        dict_['pictureAuth'] = 'true' if sql_result['picture_auth'] == 'true' else 'false'

        if sql_result['attributes'] != "null":
            dict_['attributes'] = sql_result['attributes']

        if sql_result['group_id'] != "null":
            dict_['groupID'] = sql_result['group_id']

        if sql_result['description'] != "null":
            dict_['description'] = sql_result['description']

        if sql_result['period_of_validity'] != "null":
            dict_['periodOfValidity'] = sql_result['period_of_validity']

        if sql_result['sku_infos'] != "null":
            dict_['skuInfos'] = sql_result['sku_infos']

        if sql_result['sale_info'] != "null":
            dict_['saleInfo'] = sql_result['sale_info']

        if sql_result['shipping_info'] != "null":
            dict_['shippingInfo'] = sql_result['shipping_info']

        return dict_

    async def get_offer(self, form):

        async with self.application.mysql.acquire() as conn:
            async with conn.cursor(DictCursor) as cur:
                await cur.execute(f"""
                    SELECT
                        id,
                        product_id,
                        product_type,
                        category_id,
                        attributes,
                        group_id,
                        SUBJECT,
                        description,
                        LANGUAGE,
                        period_of_validity,
                        biz_type,
                        picture_auth,
                        image,
                        sku_infos,
                        sale_info,
                        shipping_info,
                        international_tradeInfo,
                        website
                    FROM
                        alibb.`alibb_container_product`
                    WHERE product_id = "{form.product_id.data}"
                        AND member_id = "{self.current_user['member_id']}"
                        AND is_use = '0'
                """)
                result = await cur.fetchone()

        return result

    @authenticated_async
    async def get(self):

        body = loads(self.request.body.decode('utf8'))

        form = InsertAttributeForm.from_json(body)

        if not form.validate():
            for error in form.errors:
                self.set_status(403)
                return await self.finish({"error": form.errors[error][0]})

        result = await self.get_offer(form)

        if not result:
            self.set_status(403)
            return await self.finish({"error": "商品不存在"})

        # --------------------发布商品---------------------------

        api = AddOfferApi(self.current_user['access_token'],
                          self.application.session,
                          self.application.settings['app_key'])

        # 拼接参数
        try:
            param = self.join_param(result)
        except Exception as e:
            self.set_status(403)
            return await self.finish({"error": str(e)})

        status_code, resp = await api.post(param)

        if status_code == 401:
            self.set_status(401)
            return await self.finish({"error": "用户授权过期"})
        elif status_code != 200:
            self.set_status(403)
            await self.write_error_log(self.current_user['member_id'], "恢复商品失败", f"id: {result['product_id']}")
            return await self.finish({"error": resp})

        # -----------------逻辑删除已经恢复的商品---------------------
        sql = f"""
            UPDATE
              alibb.`alibb_container_product`
            SET
              is_use = '1'
            WHERE product_id = '{result['product_id']}'
              AND member_id = "{self.current_user['member_id']}"
            """
        await self.insert(sql, "逻辑删除已恢复商品失败", sql)

        await self.finish({"msg": "恢复成功"})


class AddOfferHandler(BaseHandler, ABC):

    @staticmethod
    def dual_attribute(dict_):
        return str(dict_).replace(" ", "").replace("True", "'true'").replace("False", "'false'").replace(
            "+", "加").replace("%", "百分比").replace("&ge;", "大于等于").replace("&le;", "小于等于")

    @staticmethod
    def dual_desc(body):
        # 转换html转义
        # 转义%
        # 转义特殊符号
        # 转义一些第三方模板带来的'
        return body.replace("&nbsp;", "").replace("&amp;", "").replace("&rdquo;", "").replace("&ldquo;", ""). \
            replace("+", "").replace("%", "").replace("&omega;", "欧姆").replace("'", "\"").replace("&lsquo;", ""). \
            replace("&plusmn;", "加减号").replace("&rarr;", "").replace("&larr;", "").replace("&ge;", "大于等于"). \
            replace("&le;", "小于等于")

    @staticmethod
    def dual_image(pic_list):
        arg = {"images": list(map(lambda x: "https://cbu01.alicdn.com/" + x, pic_list['images']))}

        return str(arg).replace(" ", "")

    def join_sql(self, body):

        if body['language'] != "CHINESE":
            raise Exception("非中文站商品")

        sql = f"""
        INSERT INTO alibb.`alibb_container_product` (
            member_id,
            product_id,
            product_type,
            category_id,
            attributes,
            group_id,
            SUBJECT,
            description,
            LANGUAGE,
            period_of_validity,
            biz_type,
            picture_auth,
            image,
            sku_infos,
            sale_info,
            shipping_info,
            website
        )
        VALUES 
        (
            "{self.current_user["member_id"]}",
            "{body["productID"]}",
            "{body["productType"]}",
            "{body["categoryID"]}",
            "{self.dual_attribute(body['attributes']) if body.get('attributes') else 'null'}",
            "{str(body["groupID"]) if body.get("groupID") else 'null'}",
            "{body["subject"]}",
            '{self.dual_desc(body["description"]) if body.get("description") else 'null'}',
            "{body["language"]}",
            "{body["periodOfValidity"] if body.get("periodOfValidity") else 'null'}",
            "{body["bizType"]}",
            "{'true' if body["pictureAuth"] else 'false'}",
            "{self.dual_image(body["image"])}",
            "{self.dual_attribute(body['skuInfos']) if body.get("skuInfos") else 'null'}",
            "{self.dual_attribute(body["saleInfo"]) if body.get("saleInfo") else 'null'}",
            "{str(body["shippingInfo"]).replace(" ", "") if body.get("shippingInfo") else 'null'}",
            "1688"
        )
        """

        return sql

    @authenticated_async
    async def get(self):

        body = loads(self.request.body.decode('utf8'))

        # 拼接sql
        try:
            sql = self.join_sql(body)
        except Exception as e:
            self.set_status(403)
            return await self.finish({"error": str(e)})

        try:
            await self.insert(sql, "保存商品失败", f"商品id: {body['productID']}")
        except Exception:
            self.set_status(403)
            return await self.finish({"error": "保存商品失败"})

        await self.finish({"msg": "保存成功"})
